package westeel.dataserver.utils;

//import com.alibaba.druid.pool.DruidDataSource;
//import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

//程序运行的过程中创建的数据源,不是配置文件里面有的
@Component
public  class DataSourceCreateHelper {
    @Value("${dataSource.initSize:5}")
    private int initializeSize;
    @Value("${dataSource.maxSize:8}")
    private int maxSize;

    public static void setDefaultDataSourceName(String defaultDataSourceName) {
        DataSourceCreateHelper.defaultDataSourceName = defaultDataSourceName;
    }

    public static String defaultDataSourceName;
    final static Logger logger = LoggerFactory.getLogger(DataSourceCreateHelper.class);
    private DataSourceCreateHelper() { }
    private static final DataSourceCreateHelper singleton = new DataSourceCreateHelper();
    public static DataSourceCreateHelper getSingleton() {
        return  singleton;
    }
//    private DataSource createDruidDataSource(Map<String,Object> props) throws Exception {
//        // 创建 ComboPooledDataSource 对象，该对象间接实现了 java 官方提供的 DataSource 接口
//        DruidDataSource ds = (DruidDataSource)DruidDataSourceFactory.createDataSource(props);
//        // 设置初始化连接数
//        ds.setInitialSize(initializeSize);
//        ds.setMaxActive(maxSize);
//        Map dsProps = copyMap(props,"jdbcUrl","url");
//        BeanUtils.populate(ds,dsProps);
//        return ds;
//    }
    private DataSource createHikDataSource(Map<String,Object> props) throws Exception {
        // 创建 ComboPooledDataSource 对象，该对象间接实现了 java 官方提供的 DataSource 接口
        HikariDataSource ds = new HikariDataSource();
        if(!props.containsKey("jdbcUrl") || !props.containsKey("driverClassName")){
            throw new SQLException("jdbcUrl and driverClassName MUST be existed!");
        }

		//ds.setConnectionTestQuery("SELECT 1");
        //生效超时
        ds.setValidationTimeout(10000);
        //只读
        ds.setReadOnly(true);
        //设置连接超时
        ds.setConnectionTimeout(60000);
        //空闲最大时长
        ds.setIdleTimeout(60000);
        //超时没有使用则释放,默认10分钟
        ds.setMaxLifetime(600000);
        //最大连接数默认20,因为数据源特别多
        ds.setMaximumPoolSize(20);
        //allow custom properties to override default values
        BeanUtils.populate(ds,props);
        return ds;
    }
    private Map copyMap(Map<String, Object> src,String ... replaceKeys) {
            Map dst = new LinkedHashMap();
            Map<String,String> replaceKeyMap = new HashedMap();
            int index = 0;
            String provKey = "";
            for(String replaceKey : replaceKeys ){
                if (index % 2 == 1){
                    replaceKeyMap.put(provKey,replaceKey);
                }
                index++;
                provKey = replaceKey;
            }
            String newKey;
            for(String key:src.keySet()){
                if(replaceKeyMap.containsKey(key)){
                    newKey = replaceKeyMap.get(key);
                } else {
                    newKey = key;
                }
                dst.put(newKey,src.get(key));
            }
            return dst;
    }

    /*** 创建数据源 如果数据源已存在不进行创建 * *@paramdataSourceConfig*/
    public void createDataSource(Set<String> dataSources, String name, Map<String,Object> props) {
        Logger logger = LoggerFactory.getLogger(DataSourceCreateHelper.class);
        //加入到缓存中

        if(dataSources.contains(name))
        {
            logger.warn("当前数据库连接已存在,不进行数据源创建");
            throw new RuntimeException("当前数据库连接已存在,不进行数据源创建");
        }
        try {
            DataSource dataSource = createHikDataSource(props);
            SpringHelper.registerSingletonBean(name, dataSource);
            dataSources.add(name);
            logger.info("数据源创建成功", name);
        } catch (Exception e) {
            logger.error("createDataSource",e);
            throw new RuntimeException("数据源创建失败");
        }
    }

    public void removeDataSource(Set<String> dataSources, String name) {
        Logger logger = LoggerFactory.getLogger(DataSourceCreateHelper.class);
        //加入到缓存中
        if(!dataSources.contains(name))
        {
            logger.warn("当前数据库连接不存在");
            throw new RuntimeException("当前数据库连接不存在");
        }
        try {
            SpringHelper.destroySingleton(name);
            dataSources.remove(name);
            logger.info("数据源删除成功", name);
        } catch (Exception e) {
            logger.error("removeDataSource",e);
            throw new RuntimeException("数据源删除失败");
        }
    }
}